from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from flask import g, jsonify, request, current_app
from app.models import User
from flask_httpauth import HTTPTokenAuth
from flask_restplus import Resource, Namespace, fields
from werkzeug.security import check_password_hash
from app.extensions import cache

auth = HTTPTokenAuth(scheme='Token')
api = Namespace("auth", description='用户登录注册类')

doc_auth = {
    'params': {'email': '用户登录email', 'password': '用户登录pssword'},
    'description': '用户登录返回Token',  # 描述
    'responses': {404: 'page not found'},  # 响应
}

model_request = api.model('request_auth', {
    'email': fields.String,
    'password': fields.String(discriminator=True)
})

doc_logout = {
    'description': '用户退出，token存入黑名单',  # 描述
    'responses': {403: 'Unauthorized access', 404: 'page not found', 200: 'logout success'},  # 响应
}


@auth.verify_token
def verify_token(token):
    print(token)
    if cache.get(token) == "过时Token清单":
        return False
    s = Serializer(current_app.config["SECRET_KEY"])
    try:
        data = s.loads(token.encode("utf-8"))
        g.data = data
        return True
    except:
        return False


@auth.error_handler
def unauthorized():
    return jsonify({"error": "Unauthorized access"}), 403


@api.route("/")
class AuthListAPI(Resource):
    @api.doc(**doc_auth)
    @api.expect(model_request)
    @api.response(200, "success", headers={"access_token": "返回用户token", "userid": "返回用户id"})
    @api.response(403, "forbidden", headers={"password": "wrong password", "email": "not found this email"})
    def post(self):
        email = request.json["email"]
        password = request.json["password"]
        user = User.query.filter_by(email=email).first()
        uid = user.id
        pwhash = user.password
        if user:
            if check_password_hash(pwhash, password):
                s = Serializer(current_app.config["SECRET_KEY"], expires_in=600)
                token = s.dumps({"email": email})
                return jsonify({"access_token": token.decode("utf-8"), "userid": uid})
            else:
                return jsonify({"password": "wrong password"})
        else:
            return jsonify({"email": "not found this email"})

    @api.doc(**doc_logout)
    def delete(self):
        cache.set(request.headers["Authorization"][6:], "过时Token清单", timeout=600)
        return {"logout": "success"}
